﻿#region Using
#if NUNIT
using System;
using System.Data;
using NMock2.Events;
using NUnit.Framework;
using TestClass = NUnit.Framework.TestFixtureAttribute;
using TestMethod = NUnit.Framework.TestAttribute;
using TestInitialize = NUnit.Framework.SetUpAttribute;
using TestCleanup = NUnit.Framework.TearDownAttribute;
using TestContext = System.Object;
#else
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Category = Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute;
#endif

using NMock2;
using NMock2.Matchers;

#endregion

namespace NMock3.Tests
{
	[TestClass]
	public class EventTests
	{
		[TestMethod]
		public void TestEventHandler1()
		{
			MockFactory factory = new MockFactory();
			Mock<IEventTests> mock = factory.CreateMock<IEventTests>();

			MockEventInvoker invoker1 = mock.Expects.One.EventBinding(e => e.Handler1 += null);
			MockEventInvoker invoker2 = mock.Expects.One.EventBinding(e => e.Handler2 += null);
			MockEventInvoker<EventArgs> invoker3 = mock.Expects.One.EventBinding<EventArgs>(e => e.Handler3 += null);
			MockEventInvoker<UnhandledExceptionEventArgs> invoker4 = mock.Expects.One.EventBinding<UnhandledExceptionEventArgs>(e => e.Handler4 += null);

			EventTestsControler controler = new EventTestsControler(mock.MockObject);

			invoker1.Invoke();
			invoker2.Invoke();
			invoker3.Invoke();
			invoker4.Invoke();

			Assert.IsTrue(controler.Handler1Called);
			Assert.IsTrue(controler.Handler2Called);
			Assert.IsTrue(controler.Handler3Called);
			Assert.IsTrue(controler.Handler3Called);

			factory.VerifyAllExpectationsHaveBeenMet();
		}
	}

	public class EventTestsControler
	{
		public bool Handler1Called { get; private set; }
		public bool Handler2Called { get; private set; }
		public bool Handler3Called { get; private set; }
		public bool Handler4Called { get; private set; }

		public EventTestsControler(IEventTests mockObject)
		{
			mockObject.Handler1 += mockObject_Handler1;
			mockObject.Handler2 += mockObject_Handler2;
			mockObject.Handler3 += mockObject_Handler3;
			mockObject.Handler4 += mockObject_Handler4;
		}

		void mockObject_Handler4(object sender, UnhandledExceptionEventArgs e)
		{
			Handler4Called = true;
		}

		void mockObject_Handler2(object sender, EventArgs e)
		{
			Handler2Called = true;
		}

		void mockObject_Handler3(object sender, EventArgs e)
		{
			Handler3Called = true;
		}

		void mockObject_Handler1(object sender, EventArgs e)
		{
			Handler1Called = true;
		}
	}

	public interface IEventTests
	{
		event EventHandler Handler1;
		event EventHandler Handler2;
		event EventHandler<EventArgs> Handler3;
		event EventHandler<UnhandledExceptionEventArgs> Handler4;
	}
}
